package legumes.client.ui.admin.stall;

import java.util.List;
import java.util.Map;

import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.SaveStallCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.widgets.utils.Formatters;
import legumes.shared.domain.OnSaleProduct;
import legumes.shared.domain.Price;
import legumes.shared.domain.Product;
import legumes.shared.domain.Quantity;
import legumes.shared.domain.SellSession;
import legumes.shared.domain.Stall;
import legumes.shared.domain.Unit;

import com.google.gwt.core.client.GWT;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;

public class BasketOutsidePanel extends VLayout {

	private ListGrid listGrid;
	private SellSession sellSession;
	
	public BasketOutsidePanel() {
		super();
		setWidth100();
		setHeight("50%");
		
		setShowEdges(true);
		setMembersMargin(5);  
        setLayoutMargin(10); 
        
		build();
	}
	

	public void initData(SellSession sellSession_){
		sellSession = sellSession_;
		List<OnSaleProduct> products = sellSession_.getStall().getOnSaleProducts();
		int i = 0;
		ListGridRecord[] records = new ListGridRecord[products.size()];
		for (OnSaleProduct p : products) {
			ListGridRecord record = new ListGridRecord();
			record.setAttribute("adminBasketOutsideIsSelected", true);
			record.setAttribute("adminBasketOutsidePrice", new Float(p.getPrice().getAmount()) );
			record.setAttribute("adminBasketOutsideProductName", p.getProduct().getName());
			record.setAttribute("adminBasketOutsideQuantity", p.getPrice().getQuantity().getValue());
			record.setAttribute("adminBasketOutsideQuantityUnit", p.getPrice().getQuantity().getUnitAsEnum().getDisplayName());
			
//			if(p != null && p.getProduct() != null &&  p.getProduct().getProductType() != null){
//				record.setAttribute("adminBasketOutsideCat", p.getProduct().getProductType() );
//			} else {
//				record.setAttribute("adminBasketOutsideCat", "Legumes");
//			}
			records[i] = record;
			i++;
		}
		listGrid.setRecords(records);
	}
	
	private void saveOnServer(){
		RPCCallSequencer callSequencer = new RPCCallSequencer("Enregistrement en cours...");
		final SaveStallCallback saveStallCallback = new SaveStallCallback(
				sellSession.getStall());
		callSequencer.addCall(saveStallCallback);
		callSequencer.callSequence();
	}
	
	
	private void build(){
		
		ToolStrip toolStrip = new ToolStrip();
		toolStrip.setWidth100();
		toolStrip.setHeight(21);
		
		ToolStripButton addProductButton = new ToolStripButton();  
		addProductButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				ListGridRecord record = new ListGridRecord();
				record.setAttribute("adminBasketOutsideIsSelected", true);
				record.setAttribute("adminBasketOutsidePrice", new Float(0f));
				record.setAttribute("adminBasketOutsideQuantity", new Float(1f));
				record.setAttribute("adminBasketOutsideQuantityUnit", Unit.KG.getDisplayName());
				record.setAttribute("adminBasketOutsideCat", "Legumes");
				
				listGrid.startEditingNew(record);
			}
		});
		addProductButton.setIcon(PNResources.INSTANCE.addIcon().getURL());  
		addProductButton.setTooltip("Ajouter un produit");  
        toolStrip.addButton(addProductButton);
       
        ToolStripButton delProductButton = new ToolStripButton();  
        delProductButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				final ListGridRecord [] selectedRecords = listGrid.getSelection();
				
				BooleanCallback bc = new BooleanCallback() {
					
					@Override
					public void execute(Boolean value) {
						if( value.booleanValue() ){
							
							for(ListGridRecord r : selectedRecords){
								String productName = r.getAttributeAsString("adminBasketOutsideProductName");
								
								OnSaleProduct onSaleProduct = sellSession.getStall().findOnSaleProduct(productName);
								if( onSaleProduct != null ){
									sellSession.getStall().removeOnSaleProduct(onSaleProduct);
								} else {
									GWT.log("Error while removing, out of basket, the onSaleProduct '" + productName + "' not found.");
								}
							}
							saveOnServer();
							
							listGrid.removeSelectedData();
							listGrid.refreshFields();
						}
					}
				};
				if(selectedRecords == null || selectedRecords.length <= 0){
					SC.say("Vous devez s&eacute;lectionner des produits dans la grille pour les supprimer.");
				} else if(selectedRecords.length==1) {
					String productName = selectedRecords[0].getAttributeAsString("adminBasketOutsideProductName");
					SC.confirm("Suppression d'un produit hors panier", 
							"Etes vous sur de vouloir supprimer le produit " + productName + "  ?", 
							bc);
				} else {
					SC.confirm("Suppression de produits du panier", 
							"Etes vous sur de vouloir supprimer les " + selectedRecords.length +" produits s&eacute;lectionn&eacute;s hors panier ?", 
							bc);
				}
			}
		});
        delProductButton.setIcon(PNResources.INSTANCE.deleteIcon().getURL());  
        delProductButton.setTooltip("Supprimer les produits s&eacute;lectionn&eacute;s...");  
        toolStrip.addButton(delProductButton);
        
        toolStrip.addFill();
        StaticTextItem sti = 
			new StaticTextItem("adminHeaderInBasketGrid", "");
		sti.setWrap(false);
		sti.setShowTitle(false);
		sti.setValue("Contenu hors panier");
		toolStrip.addFormItem(sti);
		toolStrip.addFill();
        
		listGrid = new ListGrid(); 
		listGrid.setShowRollOverCanvas(true);  
		listGrid.setCanEdit(true);  
		listGrid.setWidth100();
        listGrid.setHeight("50%");
//		listGrid.setSelectOnEdit(true);
        listGrid.setCellHeight(22);  
        listGrid.setShowAllRecords(true);
        listGrid.setSelectionType(SelectionStyle.SIMPLE);  
        listGrid.setSelectionAppearance(SelectionAppearance.ROW_STYLE);
        listGrid.setEditByCell(false);
        listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX); 
        
        listGrid.setGroupByField("adminBasketOutsideCat");  
        listGrid.setGroupStartOpen("all");
        
        
        ListGridField categoryField = new ListGridField("adminBasketOutsideCat", "Cat&eacute;gorie");  
        categoryField.setCanEdit(true);
        
        ListGridField libelleField = new ListGridField("adminBasketOutsideProductName", "Produit", 100);  
        libelleField.setCanEdit(true);
  
        ListGridField quantityAmountField = new ListGridField("adminBasketOutsideQuantity", "Quantit&eacute;", 50);
        quantityAmountField.setType(ListGridFieldType.FLOAT);
        quantityAmountField.setAlign(Alignment.RIGHT);
        quantityAmountField.setCanEdit(true);
        
        ListGridField quantityUnitField = new ListGridField("adminBasketOutsideQuantityUnit", "Unit&eacute; Quantit&eacute;", 100);
        quantityUnitField.setValueMap(Unit.G.getDisplayName(), Unit.KG.getDisplayName(), Unit.L.getDisplayName(), Unit.UNITY.getDisplayName());
        quantityUnitField.setAlign(Alignment.LEFT);
        quantityUnitField.setCanEdit(true);
        
        ListGridField priceField = new ListGridField("adminBasketOutsidePrice", "Prix", 70); 
        priceField.setType(ListGridFieldType.FLOAT);
        priceField.setCanEdit(true);
        priceField.setAlign(Alignment.RIGHT);
        
        priceField.setCellFormatter(new CellFormatter() {  
            public String format(Object value_, ListGridRecord record_0, int rowNum, int colNum) {  
            	 return value_ == null ? null : Formatters.formatPrice(value_, true);
            }  
        });
  
        listGrid.setFields(libelleField, priceField, quantityAmountField,  quantityUnitField, categoryField);  

        listGrid.addEditCompleteHandler(new EditCompleteHandler() {
			
        	private String updateProductName(Stall stall_, String newProductName_, String oldProductName_){
        		String updatedProductName = null;
        		if( newProductName_ != null){
        			OnSaleProduct onSaleProductToAdd = stall_.findOnSaleProduct(oldProductName_);
					if(onSaleProductToAdd==null){
						onSaleProductToAdd = new OnSaleProduct();
						onSaleProductToAdd.setId( stall_.getMenu().getDate() );
						stall_.getOnSaleProducts().add(onSaleProductToAdd);
					}
					
					Product p = onSaleProductToAdd.getProduct();
					if( onSaleProductToAdd.getProduct() != null ){
						p.setName(newProductName_);
					} else {
						p = new Product();
						p.setName(newProductName_);
						onSaleProductToAdd.setProduct(p);
					}
					
					updatedProductName = newProductName_;
        		} else {
        			updatedProductName = oldProductName_;
        		}
        		return updatedProductName;
        	}
        	
        	private Price createPrice(Number newProductPrice_, Number oldProductPrice_
        	){
        		Price price = new Price();
        		if( newProductPrice_ == null && oldProductPrice_ != null){
        			price.setAmount( oldProductPrice_.floatValue() );
        		} else if( newProductPrice_ != null ){
        			price.setAmount( newProductPrice_.floatValue() );
        		} else {
        			price.setAmount( 0f );
        		}
        		return price;
        	}
        	
        	private Quantity createQuantity(Number newQuantite_, Number oldQuantite_,
        			String newQuantiteUnit_, String oldQuantiteUnit
        	){
        		Quantity q = new Quantity();
        		if( newQuantite_ == null && oldQuantite_ != null){
        			q.setValue( oldQuantite_.floatValue() );
        		} else if( newQuantite_ != null ){
        			q.setValue( newQuantite_.floatValue() );
        		} else {
        			q.setValue( 0f );
        		}
        		
        		if( newQuantiteUnit_ == null && oldQuantiteUnit != null){
        			q.setUnit( Unit.fromDisplayName(oldQuantiteUnit).name() );
        		} else if( newQuantiteUnit_ != null ){
        			q.setUnit( Unit.fromDisplayName(newQuantiteUnit_).name() );
        		} else {
        			q.setUnit( Unit.KG.name() );
        		}
        		
        		return q;
        	}
        	
        	private void updatePriceAndQuantity(OnSaleProduct onSaleProductToAdd_, 
        			Number newProductPrice_, Number oldProductPrice_,
        			Number newQuantite_, Number oldQuantite_,
        			String newQuantiteUnit_, String oldQuantiteUnit_
        	){
        		Price price = createPrice(newProductPrice_, oldProductPrice_);
				price.setQuantity( createQuantity(newQuantite_, oldQuantite_, newQuantiteUnit_, oldQuantiteUnit_) );
				onSaleProductToAdd_.setPrice(price);
        	}
        	
//        	private void updateCat(Product p_, String newCat_, String oldCat_){
//        		if( newCat_ == null && oldCat_ != null){
//        			p_.setProductType( oldCat_ );
//        		} else if( newCat_ != null ){
//        			p_.setProductType( newCat_ );
//        		} else {
//        			p_.setProductType( "" );
//        		}
//        	}
        	
			@Override
			public void onEditComplete(EditCompleteEvent event) {
				Map<String, Object> newValues = (Map<String, Object>)event.getNewValues();
				Record oldValues = event.getOldRecord();
				try{
					String newProductName = (String)newValues.get("adminBasketOutsideProductName");
					Number newPrice = (Number)newValues.get("adminBasketOutsidePrice");
					Number newQuantite = (Number)newValues.get("adminBasketOutsideQuantity");
					String newQuantiteUnit = (String)newValues.get("adminBasketOutsideQuantityUnit");
					String newCategorie = (String)newValues.get("adminBasketOutsideCat");
					
					String oldProductName = oldValues==null?null:(String)oldValues.getAttribute("adminBasketOutsideProductName");
					Number oldPrice = oldValues==null?null:(Number)oldValues.getAttributeAsFloat("adminBasketOutsidePrice");
					Number oldQuantite = oldValues==null?null:(Number)oldValues.getAttributeAsFloat("adminBasketOutsideQuantity");
					String oldQuantiteUnit = oldValues==null?null:(String)oldValues.getAttribute("adminBasketOutsideQuantityUnit");
					String oldCategorie = oldValues==null?null:(String)oldValues.getAttribute("adminBasketOutsideCat");
					
					Stall stall = sellSession.getStall();
					String updatedProductName = updateProductName(stall, newProductName, oldProductName);
					
					OnSaleProduct onSaleProductToAdd = stall.findOnSaleProduct(updatedProductName);
					if(onSaleProductToAdd==null){
						onSaleProductToAdd = new OnSaleProduct();
						onSaleProductToAdd.setId( stall.getMenu().getDate() );
						stall.getOnSaleProducts().add(onSaleProductToAdd);
					}
					updatePriceAndQuantity(onSaleProductToAdd, newPrice, oldPrice, 
							newQuantite, oldQuantite, newQuantiteUnit, oldQuantiteUnit);
//					updateCat(onSaleProductToAdd.getProduct(), newCategorie, oldCategorie);
					
					saveOnServer();
				} catch(Exception e_){
					GWT.log("Basket outside panel : onEditComplete ", e_);
				}
			}
		});
        
        
        setMembers(toolStrip, listGrid);
	}
}
